package org.paboo.chart.qrcode;

import java.awt.image.BufferedImage;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.EnumMap;
import java.util.Map;

import org.paboo.util.LoggerFactoryUtils;
import org.paboo.util.ZxingImage;

import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.google.zxing.qrcode.encoder.Encoder;
import com.google.zxing.qrcode.encoder.QRCode;

public class ZxingUtil {

    private static LoggerFactoryUtils logger = LoggerFactoryUtils.getInstance().load(ZxingUtil.class);

    public static QRCode encode(QREntity p)
            throws WriterException {
        Map<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class);
        if (!StandardCharsets.ISO_8859_1.equals(p.getEncoding())) {
            // Only set if not QR code default
            hints.put(EncodeHintType.CHARACTER_SET, p.getEncoding());
        }
        return Encoder.encode(p.getData(), p.getEcLevel(), hints);
    }


    public static BufferedImage encodeWithImg(QREntity p)
            throws WriterException {
        BitMatrix matrix = ZxingImage.resultDecodec(encode(p).getMatrix(), p.getWidth(), p.getHeight(),
                p.getMargin());
        logger.debug("BitMatrix is " + ((matrix == null)?"NULL":"NOT NULL"));
        return ZxingImage.toBufferedImage(matrix, p.getBackgroundColor(), p.getForegroundColor());
    }

    public static void encodeWithSVG(QREntity p, OutputStream out)
            throws WriterException {
        ZxingImage.toSVGImage(
                ZxingImage.resultDecodec(
                        ZxingUtil.encode(p).getMatrix(), p.getWidth(), p.getHeight(), p.getMargin()),
                out, p.getBackgroundColor(), p.getForegroundColor());
    }

    
    public static ErrorCorrectionLevel parseErrorCorrectLevel(String ecl) {
    	if ("L".equals(ecl) || "l".equals(ecl) ) {
    		return ErrorCorrectionLevel.L;
    	} else if ("Q".equals(ecl) || "q".equals(ecl) ) {
    		return ErrorCorrectionLevel.Q;
    	} else if ("M".equals(ecl) || "m".equals(ecl) ) {
	    	return ErrorCorrectionLevel.M;
    	} else if ("H".equals(ecl) || "h".equals(ecl) ) {
    		return ErrorCorrectionLevel.H;
    	} else {
    		throw new IllegalArgumentException("invalid error correct level : " + ecl);
    	}
    }
}
